# author: axin
# date: 2021/4/22 14:23
# description:

from rest_framework import serializers
from django.db import transaction

from goods.models import SKU, GoodsCategory, SPU, SPUSpecification, SpecificationOption, SKUSpecification


class SKUSpecificationSerializer(serializers.ModelSerializer):
    """
        sku具体规格表数据
    """
    spec_id = serializers.IntegerField()
    option_id = serializers.IntegerField()

    class Meta:
        model = SKUSpecification
        fields = ("spec_id", 'option_id')


class SKUSerializers(serializers.ModelSerializer):
    """
        SKU序列化器
    """
    spu_id = serializers.IntegerField()
    category_id = serializers.IntegerField()

    #
    specs = SKUSpecificationSerializer(read_only=True, many=True)

    class Meta:
        model = SKU
        fields = '__all__'
        read_only_fields = ('spu', 'category')

    # @transaction.atomic()     # 开启事务的第一种方式，装饰器
    def create(self, validated_data):
        """
            对数据库的保存方法进行重写，让他可以保存两张表（sku表和sku具体规格表）---事务
        :param validated_data:
        :return:
        """
        specs = self.context['request'].data.get('specs')
        # 开启事务第二种方式
        with transaction.atomic():
            # 1.设置保存点
            save_point = transaction.savepoint()
            try:
                # 保存sku表
                sku = SKU.objects.create(**validated_data)
                # 保存sku具体规格表
                for spec in specs:
                    SKUSpecification.objects.create(spec_id=spec['spec_id'], option_id=spec['option_id'], sku=sku)
            except:
                # 进行回滚操作
                transaction.savepoint_rollback(save_point)
                raise serializers.ValidationError('保存失败')
            else:
                # 提交
                transaction.savepoint_commit(save_point)
                return sku

        def update(self, instance, validated_data):
            """
                对数据库的更新方法进行重写，让他可以保存两张表（sku表和sku具体规格表）---事务
            :param validated_data:
            :return:
            """
            specs = self.context['request'].data.get('specs')
            # 开启事务第二种方式
            with transaction.atomic():
                # 1.设置保存点
                save_point = transaction.savepoint()
                try:
                    # 修改sku表
                    sku = SKU.objects.update(**validated_data)
                    # 修改sku具体规格表
                    for spec in specs:
                        # SKUSpecification.objects.update(spec_id=spec['spec_id'], option_id=spec['option_id'], sku=sku)
                        SKUSpecification.objects.filter(sku=instance).update(**spec)
                except:
                    # 进行回滚操作
                    transaction.savepoint_rollback(save_point)
                    raise serializers.ValidationError('保存失败')
                else:
                    # 提交
                    transaction.savepoint_commit(save_point)
                    return instance


class GoodsCategorySerializers(serializers.ModelSerializer):
    """
        商品分类序列化器
    """

    class Meta:
        model = GoodsCategory
        fields = "__all__"


class SpecificationOptionSerializers(serializers.ModelSerializer):
    """
        SPU规格选项序列化器
    """

    class Meta:
        model = SpecificationOption
        fields = "__all__"


class SPUSpecificationSerializers(serializers.ModelSerializer):
    """
        spu规格序列化器
    """
    options = SpecificationOptionSerializers(many=True)

    # 因为前面的model表里有relate_name，为options，所以采用上面的形式
    # 如果没有则使用表名小写_set的方法  specificationoption_set=SpecificationOption(many=True)

    class Meta:
        model = SPUSpecification
        fields = "__all__"
